package com.xm.utils.common;


import lombok.Getter;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 通用的接口响应
 *
 * @param <T>
 */
@Getter
@NoArgsConstructor
public class ApiResponse<T> implements Serializable {
    public static final String SUCCESS_CODE = "200";
    public static final String SUCCESS_MSG = "SUCCESS";
    public static final String FAIL_CODE = "500";
    public static final String FAIL_MSG = "FAIL";

    private String code;
    private String msg;
    private T data;

    public ApiResponse(String code, String msg) {
        this.code = code;
        this.msg = msg;

    }

    public static <T> ApiResponse<T> success() {
        return new ApiResponse<>(SUCCESS_CODE, SUCCESS_MSG);
    }

    public static <T> ApiResponse<T> error() {
        return new ApiResponse<>(FAIL_CODE, FAIL_MSG);
    }

    public static <T> ApiResponse<T> success(T data) {
        ApiResponse<T> success = success();
        return success.setData(data);
    }

    public static <T> ApiResponse<T> error(String message) {
        return new ApiResponse<>(FAIL_CODE, message);
    }

    public static <T> ApiResponse<T> error(String code, String message) {
        return new ApiResponse<>(code, message);
    }

    public boolean isSuccess() {
        return SUCCESS_CODE.equals(code);
    }

    public ApiResponse<T> setCode(String code) {
        this.code = code;
        return this;
    }

    public ApiResponse<T> setMsg(String msg) {
        this.msg = msg;
        return this;
    }


    public ApiResponse<T> setData(T data) {
        this.data = data;
        return this;
    }

    public <R> R onSuccess(Function<T, R> function) {
        if (SUCCESS_CODE.equals(code)) {
            return function.apply(data);
        }
        return null;
    }

    public void onSuccess(Consumer<T> consumer) {
        if (SUCCESS_CODE.equals(code)) {
            consumer.accept(data);
        }
    }

    public void onError(Consumer<T> consumer) {
        if (!SUCCESS_CODE.equals(code)) {
            consumer.accept(data);
        }
    }

    public <R> R onError(Function<T, R> function) {
        if (!SUCCESS_CODE.equals(code)) {
            function.apply(data);
        }
        return null;
    }

}

